package fons.navigator.views.quadrant;

import java.awt.Color;
import java.awt.Font;
import java.awt.Paint;
import java.awt.Stroke;
import java.awt.geom.Point2D;

import edu.umd.cs.piccolo.PNode;
import edu.umd.cs.piccolo.nodes.PText;
import edu.umd.cs.piccolox.util.PFixedWidthStroke;
import fons.navigator.util.box2d.DynamicallyPlaceable;
import fons.navigator.views.piemap.Anchor;

public class SpiralDescription extends PNode implements DynamicallyPlaceable {
	private static final long serialVersionUID = 1L;
	
	private final Spiral spiral;
	private final String weightAttr;
	private final double stickyness;
	private final PText text;
	
	private Anchor anchor;
	private boolean shared = false;
	private SpiralDescription sharedDescription;
	private static final Paint ANCHOR_STROKE_PAINT = new Color(20, 20, 20, 100);
	private static final Stroke ANCHOR_STROKE = new PFixedWidthStroke(1);
	
	public SpiralDescription(Spiral spiral, String attr, double stickyness) {
		this.spiral = spiral;
		this.weightAttr = attr;
		this.stickyness = stickyness;
		
		text = new PText(weightAttr);
		addChild(text);
	}

	@Override
	public Point2D getGlobalOrigin() {
		return this.getParent().getGlobalTranslation();
	}

	@Override
	public ShapeType getShapeType() {
		return ShapeType.RECTANGLE;
	}

	@Override
	public double getShapeRadius() {
		return 0;
	}

	@Override
	public double getShapeHeight() {
		return this.text.getHeight();
	}

	@Override
	public double getShapeWidth() {
		return this.text.getWidth();
	}

	@Override
	public void placeAt(Point2D globalPoint) {
		globalPoint.setLocation(globalPoint.getX()-this.text.getFullBounds().getWidth()/2.0,
				globalPoint.getY()-this.text.getFullBounds().getHeight()/2.0);
		this.setGlobalTranslation(globalPoint);
		
		if (shared) {
			if (anchor != null) removeChild(anchor);
			anchor = Anchor.fromTo(this,
						this.text.localToParent(this.text.globalToLocal(sharedDescription.text.getGlobalFullBounds().getCenter2D())),								
						getParent().getGlobalTranslation());
			addChild(anchor);

			anchor.setStrokePaint(ANCHOR_STROKE_PAINT);
			anchor.setStroke(ANCHOR_STROKE);
			anchor.moveToBack();
			text.setVisible(false);
			
		} else {
			if (anchor != null) removeChild(anchor);
			anchor = Anchor.fromTo(this, this.text.localToParent(this.text.getFullBounds().getCenter2D()),
					getParent().getGlobalTranslation());

			final Point2D myGlobalCenter = text.getGlobalBounds().getCenter2D();

			int neighbours = 0;
			for (Spiral spiral: this.spiral.getVisualSpiral().getSpirals()) {
				for (SpiralDescription neighbour: spiral.getDescriptions()) {
					if (neighbour.getVisible() && neighbour != this) {
						Point2D globalCenter = neighbour.text.getGlobalFullBounds().getCenter2D();

						final double distance = Math.sqrt(
								(globalCenter.getX() - myGlobalCenter.getX())
								*(globalCenter.getX() - myGlobalCenter.getX())
								+(globalCenter.getY() - myGlobalCenter.getY())
								*(globalCenter.getY() - myGlobalCenter.getY()));

						if (distance < 100) {
							neighbours++;
							if (neighbour.weightAttr.equals(this.weightAttr)) {
								neighbour.sharedDescription = this;
								neighbour.shared = true;
							}
						}
					}
				}
			}

			if (anchor.getLength() > 40 || neighbours > 0) {
				addChild(anchor);
				anchor.setStrokePaint(ANCHOR_STROKE_PAINT);
				anchor.setStroke(ANCHOR_STROKE);
				anchor.moveToBack();

			} else {
				anchor = null;
			}
			
			text.setVisible(true);
		}
		
		shared = false;
	}

	@Override
	public double getAnchorRadius() {
		return 10.0;
	}

	@Override
	public double getMass() {
		return stickyness;
	}

	public void setFont(Font font) {
		this.text.setFont(font);
	}

}
